#!/usr/bin/env python
#
# Author: Ben Holroyd <holroyd.ben@gmail.com>
# License: GPL 3.0+
#
# This script requires python-mpd
#
# Usage:
# Put an entry in ~/.config/openbox/menu.xml:
# <menu id="mpd" label="MPD" execute="~/.config/openbox/scripts/ompb.py" />
#
import mpd, os, sys, socket
mpdport = 6600
musicfolder ='/home/eddie/Music'
filelist = False  #potentially slow and unwieldy with a large collection of music
playlist = False #same for this
program = sys.argv[0]

client = mpd.MPDClient()  
try:
    client.connect("localhost", mpdport)    
except socket.error:
    print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    print "<openbox_pipe_menu>"
    print "  <item label=\"MPD not running, click to start\">"
    print "    <action name=\"Execute\"><execute>mpd</execute></action>"
    print "  </item>"
    print "</openbox_pipe_menu>"
    sys.exit(0)    

song = client.currentsong()                      
stats = client.stats()
status = client.status() 

def play():
    if status['state'] == "stop" or status['state'] == "pause":
        client.play()
    elif status['state'] == "play":
        client.pause()
    
def volume(vol):
    if vol == "up":
        client.setvol(int(status['volume'])+10)
    elif vol == "down":
        client.setvol(int(status['volume'])-10)
           
try:
    if (sys.argv[1] == "play"):       play()
    elif (sys.argv[1] == "stop"):     client.stop()
    elif (sys.argv[1] == "prev"):     client.previous()
    elif (sys.argv[1] == "next"):     client.next()
    elif (sys.argv[1] == "add"):      client.add(sys.argv[2]); client.play()
    elif (sys.argv[1] == "clear"):    client.clear()
    elif (sys.argv[1] == "volume"):   volume(sys.argv[2])
    elif (sys.argv[1] == "playlist"): 
        client.delete(client.playlist().index(sys.argv[2]))
    elif sys.argv[1] == "random":
        client.random(int(not int(client.status()['random'])and True or False))
    elif sys.argv[1] == "repeat":
        client.repeat(int(not int(client.status()['repeat'])and True or False))
except IndexError:
    pass

def item_entry(indent, label, option = '', song = ''):
    """label = label on menu, option = play/pause/stop etc, song = path to song  """
    print "%s<item label=\"%s\">"%(indent, label)
    print "%s  <action name=\"Execute\"><execute>%s %s '%s'</execute></action>" % (indent, program, option, song)
    print "%s</item>" % (indent)
    
def file_walk(dir,indent):
    """ walks through music directory building a menu to view albums"""
    files = os.listdir(dir)
    files.sort()
    for file in files:
        path = os.path.join(dir,file)
        if os.path.isdir(path):
            print "%s<menu id=\"%s\" label=\"%s\">"%(indent, file, file)
            item_entry(indent+'  ','Add all to playlist','add' ,path.replace(musicfolder,''))
            print "%s  <separator />" % indent
            file_walk(path,indent+'  ')
            print "%s</menu>" % indent
        else:
            item_entry(indent,file,'add',path.replace(musicfolder,''))          
    indent = indent[2:]

def track_info(label):
    print "  <menu id=\"%s\" label=\"%s\">"%(label,label)
    print "    <item label=\"Artist: %s\"/>" % song['artist']
    print "    <item label=\"Album: %s\"/>" % song['album']
    print "    <item label=\"Tracklength: %.2f\"/>" % ((int(song['time'])/60)+(int(song['time'])%60.0/100))  
    print "    <item label=\"Track: %s\"/>" % song['track']
    print "    <item label=\"filetype: %s\"/>" % song['file'][song['file'].rfind('.')+1:]
    #print "    <item label=\"Genre: %s\"/>" % song['genre']
    print "  </menu>"


print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
print "<openbox_pipe_menu>"
if status['state'] != "stop":
    track_info("Playing: %s - " % song['artist'])
    track_info(song['title'])
    print "  <separator />"
print "  <item label=\"Status: %s\"/>" % {'play':'Playing','pause':'Paused','stop':'Stopped'}[status['state']]    
print "  <separator />"
item_entry('  ', 'Play/Pause', 'play')    
item_entry('  ', 'Stop', 'stop')
item_entry('  ', 'Prev', 'prev')
item_entry('  ', 'Next', 'next')
print "  <separator />"
if filelist == True:
    print "  <menu id=\"Albums\" label=\"Albums\">"
    file_walk(musicfolder,'  ')
    print "  </menu>"
    print "  <separator />"
if playlist == True:
    print "  <menu id=\"Playlist\" label=\"Playlist\">"
    print "    <item label=\"Click to remove from playlist\"/>"
    print "    <separator />"
    for entries in client.playlist():
        item_entry('    ', entries, 'playlist', entries)
    print "  </menu>"
    print "  <separator />"
item_entry('  ', 'Clear Playlist', 'clear')
item_entry('  ', 'Random %s' % (int(status['random']) and '[On]' or '[Off]'), 'random')    
item_entry('  ', 'Repeat %s' % (int(status['repeat']) and '[On]' or '[Off]'), 'repeat')    
print "  <menu id=\"volume\" label=\"Volume [%s]\">" % (int(status['volume']) > 0 and status['volume']+'%' or 'mute') 
item_entry('    ', 'Volume + 10\% ', 'volume up')
item_entry('    ', 'Volume - 10\%', 'volume down')
print "  </menu>"
print "  <separator />"
print "  <menu id=\"stats\" label=\"Database Stats\">"
print "    <item label=\"Artists in database: %s\"/>" % stats['artists']
print "    <item label=\"Albums in database: %s\"/>" % stats['albums']
print "    <item label=\"Songs in database: %s\"/>" % stats['songs']
print "  </menu>"
print "</openbox_pipe_menu>"
sys.exit(0)